;;; *************************************************************************
;;;; FILE IDENTIFICATION
;;;;
;;;; Name:          tag.lisp
;;;; Purpose:       Audioscrobbler/lastfm Tag data API.
;;;; Programmer:    Nicolas Lamirault <nicolas.lamirault@gmail.com>
;;;;
;;;; This file, part of audioscrobbler, is Copyright (c) 2007 by Nicolas Lamirault
;;;;
;;;; cl-audioscrobbler users are granted the rights to distribute and use this software
;;;; as governed by the terms of the MIT License :
;;;; http://www.opensource.org/licenses/mit-license.php
;;;;
;;;; *************************************************************************


(in-package :cl-audioscrobbler)


(defun retrieve-top-tags ()
  "Get the most used tags overall."
 (get-xml-answer (format nil +top-tags+)))


(defun retrieve-top-artists (tag)
  "Get artists tagged the most times with this TAG."
  (get-xml-answer (format nil +top-artists+ tag)))


(defun retrieve-top-albums (tag)
  "Get albums tagged the most times with this TAG."
  (get-xml-answer (format nil +top-albums+ tag)))



(defun retrieve-top-tracks (tag)
  "Get tracks tagged the most times with this TAG."
  (get-xml-answer (format nil +top-tracks+ tag)))
  

;; ----------------
;; API WebServices
;; ----------------

(defun get-top-tags ()
  "A list of the most used tags overall."
  (let ((xmldoc (retrieve-top-tags)))
    (when (and (listp (cdr xmldoc))
               (listp (cadr xmldoc)))
      (loop for sexp in (cdr xmldoc)
         as name = (third (car sexp))
         as count = (fifth (car sexp))
         as url = (seventh (car sexp))
         collect (make-instance 'tag :name name
                                     :count count
                                     :url url)))))


(defun get-top-artists (tag)
  "A list of the artists tagged the most times with this TAG."
  (let ((xmldoc (retrieve-top-artists tag)))
    (when (and (listp (cdr xmldoc))
               (listp (cadr xmldoc)))
      (loop for sexp in (cdr xmldoc)
         as name = (third (first sexp))
         as count = (fifth (first sexp))
         ;;as mbid = (cadr (second sexp)) ;; doesn't work ????
         as url = (cadr (third sexp))
         as thumbnail = (cadr (fourth sexp))
         as image = (cadr (fifth sexp))
         collect (make-instance 'top-artist :name name
                                            :count count
                                            ;;:mbid mbid
                                            :url url
                                            :thumbnail thumbnail
                                            :image image)))))


(defun get-top-albums (tag)
  "A list of all albums tagged the most times with this TAG."
  (let ((xmldoc (retrieve-top-albums tag)))
    (when (and (listp (cdr xmldoc))
               (listp (cadr xmldoc)))
      (loop for sexp in (cdr xmldoc)
         as name = (third (first sexp))
         as count = (fifth (first sexp))
         ;;as artist = (third (first (second sexp)))
         as url = (second (third sexp))
         as small = (second (second (fourth sexp)))
         as medium = (second (third (fourth sexp)))
         as large = (second (fourth (fourth sexp)))
         collect (make-instance 'top-album :name name
                                           :count count
                                           :url url
                                           :small small
                                           :medium medium
                                           :large large)))))


(defun get-top-tracks (tag)
  "A list tracks tagged the most times with this TAG."
  (let ((xmldoc (retrieve-top-tracks tag)))
    (when (and (listp (cdr xmldoc))
               (listp (cadr xmldoc)))
      (loop for sexp in (cdr xmldoc)
         as name = (third (first sexp))
         as count = (fifth (first sexp))
         ;;as artist = (third (first (second sexp)))
         as url = (second (third sexp))
         as thumbnail = (second (fourth sexp))
         as image = (second (fifth sexp))
         collect (make-instance 'top-track :name name
                                           :count count
                                           :url url
                                           :thumbnail thumbnail
                                           :image image)))))